﻿#include "../../src/detail/zookeeper/service_finder_zookeeper.hh"
#include "../../src/detail/zookeeper/service_register_zookeeper.hh"
#include "../../src/detail/zookeeper/zookeeper_client.hh"
#include "../framework/unittest.hh"
#include <chrono>
#include <iostream>
#include <thread>

FIXTURE_BEGIN(test_zookeeper_client)

CASE(TestConnect1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(!client.connect("", 1000));
  ASSERT_TRUE(!client.connect("3333", 1000));
  ASSERT_TRUE(!client.connect("jjj:jjj:jjj", 1000));
  ASSERT_TRUE(!client.connect("jjjj:1111", 1000));
  ASSERT_TRUE(!client.connect("1.2.3.4:abcd", 1000));
  ASSERT_TRUE(!client.connect("1.2.3.4:111111", 1000));
  ASSERT_TRUE(!client.connect("1.2.3.4:1111", 1000));
  client.dump(std::cerr);
  std::string value;
  ASSERT_TRUE(!client.get("abc", value));
  ASSERT_TRUE(!client.exists("abc"));
  std::vector<std::string> children;
  ASSERT_TRUE(!client.get_children("abc", children));
  ASSERT_TRUE(!client.is_connected());
  ASSERT_TRUE(!client.reconnect());
  ASSERT_TRUE(!client.remove("abc"));
  client.remove_cache("abc", "123");
  ASSERT_TRUE(!client.set("abc", "123"));
  ASSERT_TRUE(!client.set_path("abc", "123"));
  client.disconnect();
}

CASE(TestConnect2) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(!client.reconnect());
}

CASE(TestSet1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 2000));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  std::string value;
  ASSERT_TRUE(client.get("/level/1", value));
  ASSERT_TRUE(value == "level_1_1");
  ASSERT_TRUE(client.get("/level/1", value));
  ASSERT_TRUE(value == "level_1_1");
  ASSERT_TRUE(client.set("/level/1", "level_1_2"));
  ASSERT_TRUE(client.get("/level/1", value));
  ASSERT_TRUE(value == "level_1_2");
  client.dump(std::cerr);
}

CASE(TestGetChildren1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  ASSERT_TRUE(client.set("/level/2", "level_2_1"));
  std::list<std::string> children;
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 2);
  // 在缓存内再获取一次
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 2);
}

CASE(TestGetChildren2) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  ASSERT_TRUE(client.set("/level/2", "level_2_1"));
  std::vector<std::string> children;
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 2);
  // 在缓存内再获取一次
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 2);
  client.dump(std::cerr);
}

CASE(TestRemove1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  ASSERT_TRUE(client.remove("/level/1"));
  ASSERT_TRUE(!client.remove("/level/1"));
}

CASE(TestRemoveCache1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  ASSERT_TRUE(client.set("/level/2", "level_2_1"));
  std::vector<std::string> children;
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 2);
  client.remove_cache("/level", "1");
  ASSERT_TRUE(client.get_children("/level", children));
  ASSERT_TRUE(children.size() == 1);
}

CASE(TestExists1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(!client.exists("inexist"));
  ASSERT_TRUE(client.set_path("/level", "level_1"));
  ASSERT_TRUE(client.set("/level/1", "level_1_1"));
  ASSERT_TRUE(client.exists("/level/1"));
}

CASE(TestExists2) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/exist1", "1"));
  ASSERT_TRUE(client.exists("/exist1"));
  ASSERT_TRUE(client.remove("/exist1"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::string value;
  ASSERT_TRUE(!client.get("/exist1", value));
}

CASE(TestSetPath1) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(client.set_path("/test_path", "1"));
  ASSERT_TRUE(client.exists("/test_path"));
}

CASE(TestSetPath2) {
  kratos::service::ZookeeperClient client;
  ASSERT_TRUE(client.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(!client.set_path("/test_path/1/2", "1"));
  ASSERT_TRUE(!client.exists("/test_path/1"));
  ASSERT_TRUE(!client.exists("/test_path/1/2"));
}

CASE(TestWatch1) {
  kratos::service::ZookeeperClient op;
  kratos::service::ZookeeperClient ob;
  ASSERT_TRUE(op.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(ob.connect("127.0.0.1:2181", 1000));
  std::string value;
  ASSERT_TRUE(!ob.get("/op_key", value));
  ASSERT_TRUE(op.set("/op_key", "1"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ASSERT_TRUE(ob.get("/op_key", value));
  ASSERT_TRUE(value == "1");
  ASSERT_TRUE(op.set("/op_key", "2"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ASSERT_TRUE(ob.get("/op_key", value));
  ASSERT_TRUE(value == "2");
}

CASE(TestWatch2) {
  kratos::service::ZookeeperClient op;
  kratos::service::ZookeeperClient ob;
  ASSERT_TRUE(op.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(ob.connect("127.0.0.1:2181", 1000));
  std::string value;
  ASSERT_TRUE(!ob.get("/op_key1", value));
  ASSERT_TRUE(op.set("/op_key1", "1"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ASSERT_TRUE(ob.get("/op_key1", value));
  ASSERT_TRUE(value == "1");
  ASSERT_TRUE(op.remove("/op_key1"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ASSERT_TRUE(!ob.get("/op_key1", value));
}

CASE(TestWatch3) {
  kratos::service::ZookeeperClient op;
  kratos::service::ZookeeperClient ob;
  ASSERT_TRUE(op.connect("127.0.0.1:2181", 1000));
  ASSERT_TRUE(ob.connect("127.0.0.1:2181", 1000));
  std::string value;
  ASSERT_TRUE(op.set("/op_key_exist1", "1"));
  ASSERT_TRUE(ob.get("/op_key_exist1", value));
  ASSERT_TRUE(op.remove("/op_key_exist1"));
  std::this_thread::sleep_for(std::chrono::seconds(1));
  ASSERT_TRUE(!ob.get("/op_key_exist1", value));
}

CASE(TestServiceFinder1) {
  kratos::service::ServiceFinderZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  // 连续启动多次
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  zk.stop();
}

CASE(TestServiceFinder2) {
  kratos::service::ServiceFinderZookeeper zk;
  ASSERT_TRUE(!zk.start("", 0));
  zk.stop();
}

CASE(TestServiceFinder3) {
  kratos::service::ServiceFinderZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 1000));
  std::list<std::string> children;
  ASSERT_TRUE(!zk.find_service("not found", children));
  ASSERT_TRUE(!zk.find_service("", children));
  ASSERT_TRUE(!zk.find_service("/abc", children));
  zk.dump(std::cerr);
  zk.stop();
}

CASE(TestServiceFinder4) {
  kratos::service::ServiceFinderZookeeper zk;
  std::list<std::string> children;
  ASSERT_TRUE(!zk.find_service("nothing", children));
  zk.dump(std::cerr);
  zk.remove_cache("a", "b");
  zk.remove_cache("", "b");
  zk.remove_cache("a", "");
  zk.stop();
}

CASE(TestServiceFinder5) {
  kratos::service::ServiceFinderZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 1000));
  std::string host;
  ASSERT_TRUE(!zk.find_service("not found", host));
  ASSERT_TRUE(!zk.find_service("", host));
  ASSERT_TRUE(!zk.find_service("/abc", host));
  zk.remove_cache("a", "b");
  zk.remove_cache("", "b");
  zk.remove_cache("a", "");
  zk.remove_cache("/a", "");
  zk.stop();
}

CASE(TestServiceRegister1) {
  kratos::service::ServiceRegisterZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  // 连续启动多次
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  ASSERT_TRUE(!zk.unregister_service("", ""));
  zk.stop();
}

CASE(TestServiceRegister2) {
  kratos::service::ServiceRegisterZookeeper zk;
  ASSERT_TRUE(!zk.start("", 0));
  ASSERT_TRUE(!zk.unregister_service("", ""));
  zk.stop();
}

CASE(TestServiceRegister3) {
  kratos::service::ServiceRegisterZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  ASSERT_TRUE(!zk.register_service("", ""));
  ASSERT_TRUE(!zk.register_service("a", ""));
  ASSERT_TRUE(!zk.register_service("", "b"));
  ASSERT_TRUE(zk.register_service("/test/1/2", "1"));
  ASSERT_TRUE(zk.unregister_service("/test/1/2", "1"));
  ASSERT_TRUE(!zk.unregister_service("/test/1/2", "1"));
  zk.stop();
}

CASE(TestServiceRegister4) {
  kratos::service::ServiceRegisterZookeeper zk;
  ASSERT_TRUE(zk.start("127.0.0.1:2181", 0));
  zk.register_service("not_found/a", "b");
  zk.stop();
}

CASE(TestServiceRegister5) {
  kratos::service::ServiceRegisterZookeeper zk;
  ASSERT_FALSE(zk.start("127.0.0.1:111111111111111111111111", 0));
  zk.stop();
}

FIXTURE_END(test_zookeeper_client)
